package com.gopay.bis.service.bank.impl.bcdl;

import java.util.Map;

import javax.annotation.Resource;

import com.gopay.common.domain.bank.boc.bcdl.queryTrans.res.B2e0035StatusRes;
import com.gopay.common.domain.bank.boc.bcdl.queryTrans.res.TransResQueryB2e0035Body;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.gopay.bis.common.util.SendSmsUtils;
import com.gopay.bis.manager.bank.bcdl.BocBcdlManager;
import com.gopay.common.constants.bank.BankConstants;
import com.gopay.common.constants.bank.BocConstants;
import com.gopay.common.constants.proccode.ProcCodeConstants;
import com.gopay.common.domain.bank.BcdlMessage;
import com.gopay.common.domain.bank.BcdlResult;
import com.gopay.common.domain.bank.bcdl.BcdlPacket;
import com.gopay.common.domain.bank.bcdl.BcdlPacketRes;
import com.gopay.common.domain.bank.boc.bcdl.ResResultStatus;
import com.gopay.common.domain.bank.boc.bcdl.batch.res.TransResBatchBody;
import com.gopay.common.domain.bank.boc.bcdl.corp.res.TransResCorpBody;
import com.gopay.common.domain.bank.boc.bcdl.interbank.res.TransResInterBankBody;
import com.gopay.common.domain.bank.boc.bcdl.query.res.TransResQueryBody;
import com.gopay.common.domain.bank.boc.bcdl.querybalance.res.TransResQueryBalanceBody;
import com.gopay.common.exception.GopayException;
import com.gopay.remote.bank.BcdlInteractRemoteService;

public class BocBcdlServiceImpl extends BaseBcdlServiceImpl implements BcdlInteractRemoteService {
	
	private static Logger logger = LoggerFactory.getLogger(BocBcdlServiceImpl.class);
	
	@Resource(name = "bocBcdlManager")
	private BocBcdlManager bocBcdlManager;
	@Resource(name = "smsConfig")
	private Map<String, String> smsConfig;

	@Override
	public BcdlResult eft(BcdlMessage base) {
		// TODO Auto-generated method stub
		BcdlResult result = new BcdlResult();
		try {
			BcdlMessage message = (BcdlMessage) base;
			if("2".equals(message.getEmergency()+"")){
				//超级网银
				TransResInterBankBody res = bocBcdlManager.payInterBank(message);
				ResResultStatus interStatus = res.getTrans().get(0).getStatus();
				result.setDefaultModel(res);
	            checkStatus(interStatus, result);
	            if(ProcCodeConstants.PROC_CODE_100S1000.equals(result.getResultCode())){
	            	ResResultStatus servStatus = res.getTrans().get(0).getInterBanks().get(0).getStatus();
	            	//checkStatus(servStatus, result);
	            	if(BocConstants.BCDL_STATUS_SUCCESS.equals(servStatus.getRspcod())){
	            		result.setBankRetCode(servStatus.getRspcod());
	                	// 交易处理中，需要后续对单时确认是否成功
	                	result.setResultCode(ProcCodeConstants.PROC_CODE_100E6066);
	                	result.setSuccess(true);
	                } else {
						//modified by zyt,2018-1-25，“是否做拒绝账务”为唯一判断失败的标准，其余非成功的均置进行中
						boolean isNeedRefund = isNeedRefund(res, base.getOrderId());
						result.setNeedRefund(isNeedRefund);
						if(isNeedRefund) {
							result.setBankRetCode(servStatus.getRspcod());
							result.setResultCode(ProcCodeConstants.PROC_CODE_100E6027);
							result.setErrorMsg(servStatus.getRspmsg());
							result.setSuccess(false);
						} else {
							result.setBankRetCode(servStatus.getRspcod());
							result.setResultCode(ProcCodeConstants.PROC_CODE_100E6066);
							result.setErrorMsg(servStatus.getRspmsg());
							result.setSuccess(false);
						}
	        		}
	            }
			} else if (message.getDcblType() == BankConstants.DCBL_CORP) {
	        	// 对公
	        	TransResCorpBody res = bocBcdlManager.payCorp(message);
	        	ResResultStatus interStatus = res.getTrans().get(0).getStatus();
	            result.setDefaultModel(res);
	            checkStatus(interStatus, result);
	            if(ProcCodeConstants.PROC_CODE_100S1000.equals(result.getResultCode())){
	            	ResResultStatus servStatus = res.getTrans().get(0).getCorps().get(0).getStatus();
	            	//checkStatus(servStatus, result);
	            	if(BocConstants.BCDL_STATUS_SUCCESS.equals(servStatus.getRspcod())
	            			||BocConstants.BCDL_STATUS_EXIST.equals(servStatus.getRspcod())){
	            		result.setBankRetCode(servStatus.getRspcod());
	            		result.setErrorMsg(servStatus.getRspmsg());
	                	// 交易处理中，需要后续对单时确认是否成功
	            		// 2017.05.05 防止中行交易挂单时再次发起支付后，CPS订单做失败处理并转线下重复付款
	                	result.setResultCode(ProcCodeConstants.PROC_CODE_100E6066);
	                	result.setSuccess(true);
	                } else {
						//modified by zyt,2018-1-25，“是否做拒绝账务”为唯一判断失败的标准，其余非成功的均置进行中
						boolean isNeedRefund = isNeedRefund(res, base.getOrderId());
						result.setNeedRefund(isNeedRefund);
						if(isNeedRefund) {
							result.setBankRetCode(servStatus.getRspcod());
							result.setResultCode(ProcCodeConstants.PROC_CODE_100E6027);
							result.setErrorMsg(servStatus.getRspmsg());
							result.setSuccess(false);
						} else {
							result.setBankRetCode(servStatus.getRspcod());
							result.setErrorMsg(servStatus.getRspmsg());
							result.setResultCode(ProcCodeConstants.PROC_CODE_100E6066);
							result.setSuccess(false);
						}
	        		}
	            }
	        } else if (message.getDcblType() == BankConstants.DCBL_PERSON) {
	        	//对私
	        	TransResBatchBody res = bocBcdlManager.payPerson(message);
	        	ResResultStatus interStatus = res.getTrans().get(0).getStatus();
	        	result.setDefaultModel(res);
	        	checkStatus(interStatus, result);
	            if(ProcCodeConstants.PROC_CODE_100S1000.equals(result.getResultCode())){
	            	ResResultStatus servStatus = res.getTrans().get(0).getBatchs().get(0).getStatus();
	            	//checkStatus(servStatus, result);
	            	if(BocConstants.BCDL_STATUS_SUCCESS.equals(servStatus.getRspcod())
	            			||BocConstants.BCDL_STATUS_EXIST.equals(servStatus.getRspcod())){
	            		result.setBankRetCode(servStatus.getRspcod());
	                	// 交易处理中，需要后续对单时确认是否成功
	            		// 2017.05.05 防止中行交易挂单时再次发起支付后，CPS订单做失败处理并转线下重复付款
	                	result.setResultCode(ProcCodeConstants.PROC_CODE_100E6066);
	                	result.setSuccess(true);
	                } else {
						//modified by zyt,2018-1-25，“是否做拒绝账务”为唯一判断失败的标准，其余非成功的均置进行中
						boolean isNeedRefund = isNeedRefund(res, base.getOrderId());
						result.setNeedRefund(isNeedRefund);
						if(isNeedRefund) {
							result.setBankRetCode(servStatus.getRspcod());
							result.setResultCode(ProcCodeConstants.PROC_CODE_100E6027);
							result.setErrorMsg(servStatus.getRspmsg());
							result.setSuccess(false);
						} else {
							result.setBankRetCode(servStatus.getRspcod());
							result.setResultCode(ProcCodeConstants.PROC_CODE_100E6066);
							result.setErrorMsg(servStatus.getRspmsg());
							result.setSuccess(false);
						}
	        		}
	            }
	        } else {
                result.setResultCode("BocBcdlServiceImpl.process:not match");
                return result;
            }
		} catch (GopayException e) {
			if(ProcCodeConstants.PROC_CODE_100E6047.equals(e.getErrCode())){
				String custName = getCustName(base.getOrderId());
				SendSmsUtils.sendSms(base.getGopayBankOrderNo(), smsConfig.get("switch"), "BOC",smsConfig.get("mobile"),e.getErrMsg()
						+"，商户名称："+custName+",金额："+base.getAmount().toString());
			}
			logger.error("BOC银企直连异常 eft", e);
			result.setResultCode(e.getErrCode());
			result.setSuccess(false);
		} catch (Exception ex){
			logger.error("BOC银企直连异常 eft error", ex);
			result.setResultCode(ProcCodeConstants.PROC_CODE_100F1002);
			result.setSuccess(false);
		}
		return result;
	}

	private void checkStatus(ResResultStatus status, BcdlResult result) {
		// TODO Auto-generated method stub
		if(BocConstants.BCDL_STATUS_SUCCESS.equals(status.getRspcod())){
        	// 银行请求成功
        	result.setResultCode(ProcCodeConstants.PROC_CODE_100S1000);
        	result.setSuccess(true);
        } else {
        	result.setBankRetCode(status.getRspcod());
			result.setResultCode(ProcCodeConstants.PROC_CODE_100E6027);
			result.setErrorMsg(status.getRspmsg());
			result.setSuccess(false);
		}
	}

	@Override
	public BcdlResult sendBank(BcdlMessage base) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public BcdlResult query(BcdlMessage base) {
		// TODO Auto-generated method stub
		BcdlResult result = new BcdlResult();
		try {
			BcdlMessage message = (BcdlMessage) base;
			TransResQueryBody res = bocBcdlManager.payQuery(message);
			ResResultStatus interStatus = res.getTrans().get(0).getStatus();
            result.setDefaultModel(res);
            checkStatus(interStatus, result);
            if(ProcCodeConstants.PROC_CODE_100S1000.equals(result.getResultCode())){
            	ResResultStatus servStatus = res.getTrans().get(0).getQuerys().get(0).getStatus();
            	//checkStatus(servStatus, result);
            	if(BocConstants.BCDL_STATUS_SUCCESS.equals(servStatus.getRspcod())){
                	// 银行请求成功
                	result.setResultCode(ProcCodeConstants.PROC_CODE_100S1000);
                	result.setSuccess(true);
                } else {
					//modified by zyt,2018-1-25，“是否做拒绝账务”为唯一判断失败的标准，其余非成功的均置进行中
					boolean isNeedRefund = isNeedRefund(res, base.getOrderId());
					result.setNeedRefund(isNeedRefund);
					if(isNeedRefund) {
						result.setBankRetCode(servStatus.getRspcod());
						result.setResultCode(ProcCodeConstants.PROC_CODE_100E6027);
						result.setErrorMsg(servStatus.getRspmsg());
						result.setSuccess(false);
					} else {
						result.setBankRetCode(servStatus.getRspcod());
						result.setResultCode(ProcCodeConstants.PROC_CODE_100E6066);
						result.setErrorMsg(servStatus.getRspmsg());
						result.setSuccess(false);
					}
				}
            }else{
            	result.setBankRetCode(interStatus.getRspcod());
            	result.setResultCode(ProcCodeConstants.PROC_CODE_100E6066);
    			result.setErrorMsg(interStatus.getRspmsg());
    			result.setSuccess(false);
            }
		} catch (GopayException e) {
			logger.error("BOC银企直连异常 query", e);
			result.setResultCode(e.getErrCode());
			result.setSuccess(false);
		} catch (Exception ex){
			logger.error("BOC银企直连异常 query error", ex);
			result.setResultCode(ProcCodeConstants.PROC_CODE_100F1002);
			result.setSuccess(false);
		}
		return result;
	}

	@Override
	public BcdlResult queryBalance(BcdlMessage base) {
		// TODO Auto-generated method stub
		BcdlResult result = new BcdlResult();
		try {
			BcdlMessage message = (BcdlMessage) base;
			TransResQueryBalanceBody res = bocBcdlManager.queryBal(message);
			ResResultStatus interStatus = res.getTrans().get(0).getStatus();
			result.setDefaultModel(res);
			checkStatus(interStatus, result);
			if(ProcCodeConstants.PROC_CODE_100S1000.equals(result.getResultCode())){
				ResResultStatus servStatus = res.getTrans().get(0).getBalance().get(0).getStatus();
				if(BocConstants.BCDL_STATUS_SUCCESS.equals(servStatus.getRspcod())){
		        	// 银行请求成功
		        	result.setResultCode(ProcCodeConstants.PROC_CODE_100S1000);
		        	result.setModel("payAccNum", res.getPayAccNum());
                    result.setModel("balance", res.getTrans().get(0).getBalance().get(0).getBalance().getAvabal());
		        	result.setSuccess(true);
		        } else {
		        	result.setBankRetCode(servStatus.getRspcod());
					result.setResultCode(ProcCodeConstants.PROC_CODE_100E6027);
					result.setErrorMsg(servStatus.getRspmsg());
					result.setSuccess(false);
				}
			}
		} catch (GopayException e) {
			logger.error("BOC银企直连异常 query bal", e);
			result.setResultCode(e.getErrCode());
			result.setSuccess(false);
		} catch (Exception ex){
			logger.error("BOC银企直连异常 query bal error", ex);
			result.setResultCode(ProcCodeConstants.PROC_CODE_100F1002);
			result.setSuccess(false);
		}
		return result;
	}

	@Override
	public BcdlResult sendBankQueryBalance(BcdlMessage base) {
		// TODO Auto-generated method stub
		return null;
	}
	
	@Override
	public BcdlResult eftRetry(BcdlMessage base) {
		// TODO Auto-generated method stub
		return null;
	}

    @Override
    public BcdlResult sendBankPacket(BcdlPacket bcdlPacket) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public BcdlPacketRes queryPacket(BcdlPacket bcdlPacket) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public BcdlResult queryAcctDetail(BcdlMessage base) {
		BcdlResult result = new BcdlResult();
		try {
			BcdlMessage message = (BcdlMessage) base;
			TransResQueryB2e0035Body res = bocBcdlManager.queryAcctDetail(message);
			result.setDefaultModel(res);
			if(ProcCodeConstants.PROC_CODE_100S1000.equals(result.getResultCode())){
				B2e0035StatusRes servStatus =res.getTrans().getTrbB2e0035Res().getB2e0035Status();
				if(BocConstants.BCDL_STATUS_SUCCESS.equals(servStatus.getRspcod())){
					// 银行请求成功
					result.setResultCode(ProcCodeConstants.PROC_CODE_100S1000);
					result.setSuccess(true);
				} else {
					result.setResultCode(ProcCodeConstants.PROC_CODE_100E6027);
					result.setErrorMsg(servStatus.getRspmsg());
					result.setSuccess(false);
				}
			}
		} catch (GopayException e) {
			logger.error("BOC银企直连异常 queryAcctDetail", e);
			result.setResultCode(e.getErrCode());
			result.setSuccess(false);
		} catch (Exception ex){
			logger.error("BOC银企直连异常 queryAcctDetail error", ex);
			result.setResultCode(ProcCodeConstants.PROC_CODE_100F1002);
			result.setSuccess(false);
		}
		return result;
    }
}
